package com.fs.common.utils;

import com.quantum.auth.Authcode;
import com.quantum.auth.RSA2048;
import com.quantum.auth.RandomTools;
import jdk.internal.dynalink.beans.StaticClass;
import org.springframework.util.ClassUtils;
import org.xidea.el.json.JSONEncoder;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.Key;
import java.util.HashMap;
import java.util.Map;

/**
 * 加密解密工具类
 */
public class AuthUtils {
    static RSA2048 rsa2048;
    static Authcode authcode;
    public static final String CRYPT_KEY = "key";
    public static final String CRYPT_VALUE = "value";

    public static RSA2048 getRsa2048() {
        if (rsa2048 == null) {
            synchronized (RSA2048.class) {
                if (rsa2048 == null) {
                    rsa2048 = new RSA2048();
                }
            }
        }
        return rsa2048;
    }

    public static Authcode getAuthCode() {
        if (authcode == null) {
            synchronized (Authcode.class) {
                if (authcode == null) {
                    authcode = new Authcode();
                }
            }
        }
        return authcode;
    }

    public static Map<String, Object> encode(String source, Key key) throws Exception {
        Map result = new HashMap<String, Object>();
        // 随机字符串
        String random = RandomTools.generateRandom();
        try {
            source = URLEncoder.encode(source, "UTF-8");
        } catch (UnsupportedEncodingException e) {
        }
        // DES加密
        String value = getAuthCode().encode(source, random);
        if (value == null) {
        }
        result.put(CRYPT_VALUE, getAuthCode().encode(source, random));


        // RSA加密
        String encrypt = null;
        try {
            encrypt = getRsa2048().encode(random, key);
        } catch (Exception e) {
        }
        if (encrypt == null) {
        }
        result.put(CRYPT_KEY, encrypt);
        return result;
    }

    public static String decode(Map<String, Object> result, Key key) throws Exception {
        String _key = result.get(CRYPT_KEY).toString();
        String _value = result.get(CRYPT_VALUE).toString();
        try {
            _key = getRsa2048().decode(_key, key);
        } catch (Exception ex) {
        }
        if (_key == null) {
        }
        // des解密
        _value = getAuthCode().decode(_value, _key);
        if (_value == null) {
        }
        try {
            _value = URLDecoder.decode(_value, "UTF-8");
        } catch (UnsupportedEncodingException e) {
        }
        return _value;
    }



    /**
     * 解密过程
     *
     * @param data
     * @return
     * @throws Exception
     */
    public static String RasAndDesDecode(Map<String, Object> data) throws Exception {
        return AuthUtils.decode(data, getKey());
    }

    /**
     * 获取公钥
     *
     * @return
     * @throws Exception
     */
    public  static Key getKey() throws Exception {
        Key key = null;
        try {
            String path = ClassUtils.getDefaultClassLoader().getResource("").getPath();
            String s = path + "public_819cfb1850ce48e1ab954aed468b2089.key";
            key = RSA2048.getKey(s);//密钥路径
        } catch (Exception ex) {
            throw ex;
        }
        return key;
    }

    /**
     * 服务参数加密
     *
     * @param serverParams
     * @return 返回加密后的密文
     * @throws Exception
     */
    public static String getPostJsonStr(String serverParams) throws Exception {
        Map<String, Object> authParams = AuthUtils.encode(serverParams, getKey());
        return URLEncoder.encode(JSONEncoder.encode(authParams), "UTF-8");
    }

    /**
     * 服务参数
     *
     * @param uid        用户Uid
     * @param serverName 服务方法名称
     * @return 服务相关参数的JSON数据
     */
    public   static String getServerJsonStr(String uid, String serverName,String keyWord) {
        Map<String, Object> conditoinMap = new HashMap<String, Object>();
        conditoinMap.put("uid", uid);
        conditoinMap.put("service", serverName);

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("keyword", keyWord);
        params.put("type", "0");

        conditoinMap.put("params", params);

        return JSONEncoder.encode(conditoinMap);
    }

}
